<?php
class View
{
	private $data;
	private $layout="";
	private $view="";
	private $controller_name="";
	private $action="";
	private $module="";
	private $root_dir="";
	private $base_url="";
	private $layout_module="";
	private static $instance=null;
	public static  function getInstance()
	{
		if(self::$instance===null)
		{
			$class=__CLASS__;
			self::$instance=new $class();
		}
		return self::$instance;
	}
	public function __construct()
	{
		if(self::$instance!==null)
		{
			throw new Exception("Registry is created!");
		}
		$this->data=array();
		$front_controller=Registry::getInstance();
		
		$route=$front_controller->get("route");
		$front_controller=$front_controller->get("frontcontroller");
		$this->root_dir=$front_controller->getRootDir();
		$this->base_url=$front_controller->getBaseUrl();
		$this->controller_name=strtolower($route->getControllerName());
		$this->action=strtolower($route->getActionName());
		$this->module=$route->getModuleName();
	}
	public  function __set($key,$value)
	{
		$this->data[$key]=$value;
	}
	
	public function __get($key)
	{
		if(array_key_exists($key,$this->data))
		{
			return $this->data[$key];
		}
		else 
		{
			return null;
		}
	}
	
	public function __isset($key)
	{
		return array_key_exists($key,$this->data);
	}
	
	public function __unset($key)
	{
		unset($this->data[$key]);
	}
	
	public function setLayout($layout)
	{
		$this->layout=$layout;
	}
	
	public function setLayoutModule($module)
	{
		$this->layout_module;
	}
	
	public function setView($view)
	{
		$this->view=$view;
	}
	public function display()
	{

		if(!empty($this->layout))
		{
			$this->showLayout();
		}
		else 
		{
			$this->showView();
		}
	}
	
	public function showLayout()
	{		
		$module=$this->module;
		if(!empty($this->layout_module))
		{
			$module=$this->layout_module;
		}
		$layout=$this->root_dir."application/modules/".$module."/layout/".$this->layout.".php";
		if(file_exists($layout))
		{
			include($layout);
		}
	}
	
	public function showView()
	{
		if(!empty($this->view))
		{			
			$view=$this->root_dir."application/modules/".$this->module."/view/".$this->controller_name."/".$this->view.".php";		
		}
		else 
		{
			$view=$this->root_dir."application/modules/".$this->module."/view/".$this->controller_name."/".$this->action.".php";
		}
		if(file_exists($view))
		{
			include($view);
		}
	}
	
	public function getRootDir()
	{
		return $this->root_dir;
	}
	
	public function getBaseUrl()
	{
		return $this->base_url;
	}
	
	public function getView()
	{
		return $this->view;
	}
	
	public function getControllerName()
	{
		return $this->controller_name;
	}
	
	public function getActionName()
	{
		return $this->action;
	}
	
	public function getModuleName()
	{
		return $this->module;
	}
	//除了前面的三个参数，后面还可以加参数加的参数是用来调用action时来传递的，后面的参数只能为数字和字符
	public static  function renderPart($module,$controller,$action)
	{
		$params=func_get_args();
		array_shift($params);
		array_shift($params);
		array_shift($params);
		
		if(!class_exists($controller."Controller"))
		{
			Loader::load(ROOTDIR."application/".$module."/".strtolower($controller)."controller.php");
		}
		$controller=$controller."Controller";
		$action=$action."Action";
		$controller_name=$controller;
		$controller=new $controller();
		if(method_exists($controller,"init")&&is_callable(array($controller_name,"init")))
		{
			$controller->init();
		}
		if(method_exists($controller,$action)&&is_callable(array($controller_name,$action)))
		{
			
			$eval='$controller->$action(';
			if(!empty($params))
			{
				foreach ($params as $value)
				{
					if(!preg_match("/^\w*$/",$value))
					{
						$value='';
					}
					$eval.="'".$value."',";
				}
				$eval=substr($eval,0,strlen($eval)-1);
			}
			$eval.=');';
			eval($eval);
			//$controller->$action();
		}
		else 
		{
			throw new Exception("The controller $controller_name's action $action is not found or is not callable");
		}
		
	}
}